package com.ushine.web.config.database;

import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.ushine.web.component.authority.handler.QueryDataPermissionInterceptor;
import com.ushine.web.component.mybatis.desensitization.plugin.DesensitizationPlugin;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * @Author: yangls
 * @Date: 2021/4/21 15:16
 * @Description: mybatis plus 主数据源配置
 * @Version 1.0
 */
@Configuration
@Primary
@MapperScan(basePackages = {"com.ushine.web.web.**.mapper",
        "com.ushine.web.component.**.mapper",
        "com.ushine.web.template.**.mapper",
        "com.ushine.web.base.**.mapper"}, sqlSessionTemplateRef = "primarySqlSessionTemplate")
public class MybatisPrimaryDruidConfig {

    @Resource
    @Qualifier("primaryDruidDataSource")
    DataSource dataSource;

    @Resource
    @Qualifier("permitPaginationInnerInterceptor")
    PaginationInnerInterceptor paginationInnerInterceptor;

    @Resource
    @Qualifier("permitGlobalConfig")
    GlobalConfig globalConfig;

    @Resource
    @Qualifier("permitDataPermissionInterceptor")
    DataPermissionInterceptor dataPermissionInterceptor;

    @Resource
    QueryDataPermissionInterceptor queryDataPermissionInterceptor;

    @Resource
    @Qualifier("permitDesensitizationPlugin")
    DesensitizationPlugin desensitizationPlugin;

    @Resource
    @Qualifier("optimisticLockerInnerInterceptor")
    OptimisticLockerInnerInterceptor permitOptimisticLockerInnerInterceptor;

    @Bean(name = "mybatisPrimarySqlSessionFactory")
    @Primary
    public SqlSessionFactory primarySqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 添加列级权限拦截器
        mybatisPlusInterceptor.addInnerInterceptor(queryDataPermissionInterceptor);
        // 添加行级权限拦截器
        mybatisPlusInterceptor.addInnerInterceptor(dataPermissionInterceptor);
        // 添加乐观锁插件
        mybatisPlusInterceptor.addInnerInterceptor(permitOptimisticLockerInnerInterceptor);
        // 添加防止全表更新与删除插件
        BlockAttackInnerInterceptor blockAttackInnerInterceptor = new BlockAttackInnerInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(blockAttackInnerInterceptor);
        // 添加分页插件
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);
        sqlSessionFactoryBean.setPlugins(mybatisPlusInterceptor);

        // 添加配置
        // 导入mybatis配置
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        // 配置打印sql语句
        configuration.setLogImpl(StdOutImpl.class);
        // 注入数据脱敏插件
        configuration.addInterceptor(desensitizationPlugin);
        sqlSessionFactoryBean.setConfiguration(configuration);

        // 自动填充字段
        sqlSessionFactoryBean.setGlobalConfig(globalConfig);
        return sqlSessionFactoryBean.getObject();
    }


    @Bean("primaryDataSourceTransactionManager")
    public DataSourceTransactionManager primaryDataSourceTransactionManager(@Qualifier("primaryDruidDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean("primarySqlSessionTemplate")
    public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("mybatisPrimarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }


}
